<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:nyext="urn:noury-extensions" xmlns:nydml="http://www.nourysolutions.com/salamanca/DML" xmlns:nyp="http://www.nourysolutions.com/salamanca/Project" exclude-result-prefixes="xsl msxsl nyext nydml nyp">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

  <xsl:variable name="dml-href" select="/nyp:project/nyp:dml/@href" />
  <xsl:variable name="dml-doc" select="document($dml-href)" />
  <xsl:variable name="namespace-base-name" select="nyp:project/@namespace" />
  <xsl:variable name="package-base-name" select="nyp:project/@package" />
  <xsl:variable name="project-base-name" select="nyp:project/@name" />
  <xsl:variable name="types">
    <xsl:call-template name="types-definition" />
  </xsl:variable>

  <xsl:include href="functions.xslt" />

  <!-- Creates a name attribute -->
  <xsl:template name="sql-name-attribute">
    <xsl:param name="element" />
    <xsl:param name="prefix" />
    <xsl:param name="suffix" />
    <xsl:param name="name" select="'name'" />
    <xsl:attribute name="{$name}">
      <xsl:choose>
        <xsl:when test="$element/@shortName">
          <xsl:value-of select="concat($prefix, $element/@shortName, $suffix)" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="concat($prefix, $element/@name, $suffix)" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:attribute>
  </xsl:template>
  
  <xsl:template name="size-attribute">
    <xsl:param name="type" />
    <xsl:param name="size" />

    <xsl:variable name="sv">
      <xsl:choose>
        <xsl:when test="$dml-doc/nydml:dml/nydml:serializable[@name=$type/@name]/nydml:sql/@size and (not($size) or (string-length($size)=0) or (/nydml:dml/nydml:serializable[@name=$type/@name]/nydml:sql/@size &lt; $size))">
          <xsl:value-of select="$dml-doc/nydml:dml/nydml:serializable[@name=$type/@name]/nydml:sql/@size" />
        </xsl:when>
        <xsl:when test="$dml-doc/nydml:dml/nydml:type[@name=$type/@name]/nydml:base/@size and (not($size) or (string-length($size)=0) or (/nydml:dml/nydml:type[@name=$type/@name]/nydml:base/@size &lt; $size))">
          <xsl:value-of select="$dml-doc/nydml:dml/nydml:type[@name=$type/@name]/nydml:base/@size" />
        </xsl:when>
        <xsl:when test="$dml-doc/nydml:dml/nydml:enum[@name=$type/@name]/nydml:base/@size and (not($size) or (string-length($size)=0) or (/nydml:dml/nydml:enum[@name=$type/@name]/nydml:base/@size &lt; $size))">
          <xsl:value-of select="$dml-doc/nydml:dml/nydml:enum[@name=$type/@name]/nydml:base/@size" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$size" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:if test="$sv and (string-length($sv) &gt; 0)">
      <xsl:attribute name="size">
        <xsl:value-of select="$sv" />
      </xsl:attribute>
    </xsl:if>
  </xsl:template>

  <!-- Creates the column attributes related to a database type description -->
  <xsl:template name="sql-type-attributes">
    <xsl:param name="type" />
    <xsl:param name="size" />
    <xsl:variable name="sv">
      <xsl:choose>
        <xsl:when test="$dml-doc/nydml:dml/nydml:serializable[@name=$type/@name]/nydml:sql/@size and (not($size) or (string-length($size)=0) or (/nydml:dml/nydml:serializable[@name=$type/@name]/nydml:sql/@size &lt; $size))">
          <xsl:value-of select="$dml-doc/nydml:dml/nydml:serializable[@name=$type/@name]/nydml:sql/@size" />
        </xsl:when>
        <xsl:when test="$dml-doc/nydml:dml/nydml:type[@name=$type/@name]/nydml:base/@size and (not($size) or (string-length($size)=0) or (/nydml:dml/nydml:type[@name=$type/@name]/nydml:base/@size &lt; $size))">
          <xsl:value-of select="$dml-doc/nydml:dml/nydml:type[@name=$type/@name]/nydml:base/@size" />
        </xsl:when>
        <xsl:when test="$dml-doc/nydml:dml/nydml:enum[@name=$type/@name]/nydml:base/@size and (not($size) or (string-length($size)=0) or (/nydml:dml/nydml:enum[@name=$type/@name]/nydml:base/@size &lt; $size))">
          <xsl:value-of select="$dml-doc/nydml:dml/nydml:enum[@name=$type/@name]/nydml:base/@size" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$size" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:choose>
      <xsl:when test="$dml-doc/nydml:dml/nydml:serializable[@name=$type/@name]">
        <xsl:attribute name="type">
          <xsl:value-of select="$dml-doc/nydml:dml/nydml:serializable[@name=$type/@name]/nydml:sql/@dbtype" />
        </xsl:attribute>
        <xsl:call-template name="size-attribute">
          <xsl:with-param name="type" select="$type" />
          <xsl:with-param name="size" select="$size" />
        </xsl:call-template>
      </xsl:when>
      <xsl:when test="$dml-doc/nydml:dml/nydml:type[@name=$type/@name]">
        <xsl:call-template name="sql-type-attributes">
          <xsl:with-param name="type" select="$dml-doc/nydml:dml/nydml:type[@name=$type/@name]/nydml:base" />
          <xsl:with-param name="size" select="$sv" />
        </xsl:call-template>
      </xsl:when>
      <xsl:when test="$dml-doc/nydml:dml/nydml:enum[@name=$type/@name]">
        <xsl:call-template name="sql-type-attributes">
          <xsl:with-param name="type" select="$dml-doc/nydml:dml/nydml:enum[@name=$type/@name]/nydml:base" />
          <xsl:with-param name="size" select="$sv" />
        </xsl:call-template>
      </xsl:when>
    </xsl:choose>
  </xsl:template>

  <!-- Creates the column attributes related to a database type description -->
  <xsl:template name="data-type-attributes">
    <xsl:param name="type" />
    <xsl:param name="required" />

    <xsl:variable name="serializable" select="$dml-doc/nydml:dml/nydml:serializable[@name=$type/@name]" />
    <xsl:variable name="enum" select="$dml-doc/nydml:dml/nydml:enum[@name=$type/@name]" />

    <xsl:choose>
      <xsl:when test="$serializable">
        <xsl:attribute name="type">
          <xsl:value-of select="$serializable/nydml:native/@type" />
        </xsl:attribute>
        <xsl:if test="($required='false') and ($serializable/nydml:native/@nullable='false')">
          <xsl:attribute name="nullable">
            <xsl:text>true</xsl:text>
          </xsl:attribute>
        </xsl:if>
        <xsl:for-each select="$serializable/nydml:sql/nydml:conversion">
          <from language='{@language}'>
            <xsl:value-of select="." />
          </from>
        </xsl:for-each>
        <xsl:for-each select="$serializable/nydml:native/nydml:conversion">
          <to language='{@language}'>
            <xsl:value-of select="." />
          </to>
        </xsl:for-each>
      </xsl:when>
      <xsl:when test="$enum">
        <xsl:attribute name="type">
          <xsl:value-of select="$type/@name" />
        </xsl:attribute>
        <xsl:if test="$required='false'">
          <xsl:attribute name="nullable">
            <xsl:text>true</xsl:text>
          </xsl:attribute>
        </xsl:if>
      </xsl:when>
      <xsl:when test="$dml-doc/nydml:dml/nydml:type[@name=$type/@name]">
        <xsl:call-template name="data-type-attributes">
          <xsl:with-param name="type" select="$dml-doc/nydml:dml/nydml:type[@name=$type/@name]/nydml:base" />
        </xsl:call-template>
      </xsl:when>
    </xsl:choose>
  </xsl:template>

  <!-- Creates the column attributes related to a database type description -->
  <xsl:template name="interface-type-attributes">
    <xsl:param name="type" />
    <xsl:param name="required" />

    <xsl:variable name="t" select="$dml-doc/nydml:dml/*[self::nydml:serializable or self::nydml:type][@name=$type/@name]" />
    <xsl:variable name="e" select="$dml-doc/nydml:dml/nydml:enum[@name=$type/@name]" />

    <xsl:attribute name="type">
      <xsl:choose>
        <xsl:when test="$e">
          <xsl:value-of select="$e/@name" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$t/nydml:native/@type" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:attribute>
    
    <xsl:choose>
      <xsl:when test="$required='false'">
        <xsl:if test="$e or $t/nydml:native/@nullable='false'">
          <xsl:attribute name="nullable">
            <xsl:text>true</xsl:text>
          </xsl:attribute>
        </xsl:if>
      </xsl:when>
      <xsl:otherwise>
        <xsl:if test="(not($e or $t/nydml:native/@nullable) or ($t/nydml:native/@nullable='true'))">
          <xsl:attribute name="required">
            <xsl:text>true</xsl:text>
          </xsl:attribute>
        </xsl:if>
      </xsl:otherwise>
    </xsl:choose>

    <xsl:call-template name="size-attribute">
      <xsl:with-param name="type" select="$type" />
      <xsl:with-param name="size" select="$type/@size" />
    </xsl:call-template>
  </xsl:template>
  
  <!-- Apply the templates on the specified element with the specified mode and name -->
  <xsl:template name="sql-foreign-item-apply">
    <xsl:param name="element" />
    <xsl:param name="mode" />
    <xsl:param name="name" />
    <xsl:param name="ft" select="false()" />
    <xsl:param name="required" select="false()" />
    <xsl:variable name="n">
      <xsl:if test="string-length($name) &gt; 0">
        <xsl:value-of select="$name" />
      </xsl:if>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="$mode='foreign-column'">
        <xsl:apply-templates select="$element" mode="sql-foreign-column">
          <xsl:with-param name="name" select="$n" />
          <xsl:with-param name="foreignTable" select="$ft" />
          <xsl:with-param name="required" select="$required" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:when test="$mode='foreign-key'">
        <xsl:apply-templates select="$element" mode="sql-foreign-key">
          <xsl:with-param name="name" select="$n" />
          <xsl:with-param name="foreignTable" select="$ft" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:when test="$mode='foreign-data'">
        <xsl:apply-templates select="$element" mode="foreign-data">
          <xsl:with-param name="name" select="$n" />
          <xsl:with-param name="foreignTable" select="$ft" />
          <xsl:with-param name="required" select="$required" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:when test="$mode='foreign-interface'">
        <xsl:apply-templates select="$element" mode="foreign-interface">
          <xsl:with-param name="name" select="$n" />
          <xsl:with-param name="foreignTable" select="$ft" />
          <xsl:with-param name="required" select="$required" />
        </xsl:apply-templates>
      </xsl:when>
    </xsl:choose>
  </xsl:template>
  
  <!-- Creates a foreign key related description -->
  <xsl:template name="sql-foreign-item">
    <xsl:param name="name" />
    <xsl:param name="mode" />
    <xsl:for-each select="$dml-doc/nydml:dml/nydml:assoc[nydml:end/@target=$name]">
      <xsl:variable name="ua" select="count(nydml:end[@multiplicity='0..1' or @multiplicity='1'])" />
      <xsl:choose>
        <xsl:when test="$ua=2">
          <xsl:if test="nydml:end[@target=$name and position()=1]">
            <xsl:variable name="oe" select="nydml:end[2]" />
            <xsl:call-template name="sql-foreign-item-apply">
              <xsl:with-param name="element" select="nydml:end[1]" />
              <xsl:with-param name="mode" select="$mode" />
              <xsl:with-param name="name" select="$oe/@name" />
              <xsl:with-param name="required" select="@multiplicity='1'" />
<!--              <xsl:with-param name="ft" select="count(nydml:attribute) &gt; 0" /> -->
            </xsl:call-template>
          </xsl:if>
        </xsl:when>
        <xsl:when test="$ua=1 and count(nydml:attribute)=0">
          <xsl:variable name="e" select="nydml:end[@target=$name and @multiplicity!='1' and @multiplicity!='0..1'][1]" />
          <xsl:if test="$e">
            <xsl:variable name="oe" select="nydml:end[@multiplicity='1' or @multiplicity='0..1']" />
            <xsl:call-template name="sql-foreign-item-apply">
              <xsl:with-param name="element" select="$e" />
              <xsl:with-param name="mode" select="$mode" />
              <xsl:with-param name="name" select="$oe/@name" />
              <xsl:with-param name="required" select="$oe/@multiplicity='1'" />
<!--              <xsl:with-param name="ft" select="count(nydml:attribute) &gt; 0" /> -->
            </xsl:call-template>
          </xsl:if>
        </xsl:when>
      </xsl:choose>
    </xsl:for-each>
    <xsl:if test="$mode='foreign-key'">
      <xsl:variable name="domain" select="$dml-doc/nydml:dml/nydml:domain[@name=$name]" />
      <xsl:if test="$domain/@extends">
        <xsl:variable name="extended" select="$dml-doc/nydml:dml/nydml:domain[@name=$domain/@extends]" />
        <foreign-key name="{concat($name, '_FK_', $extended/@name)}">
          <xsl:call-template name="sql-name-attribute">
            <xsl:with-param name="element" select="$extended" />
            <xsl:with-param name="name" select="'foreignTable'" />
          </xsl:call-template>
          <xsl:attribute name="onDelete">
            <xsl:text>cascade</xsl:text>
          </xsl:attribute>
          <xsl:apply-templates select="$domain" mode="sql-foreign-extended-references" />
        </foreign-key>
      </xsl:if>
      <xsl:for-each select="$domain/nydml:attribute[nydml:type/@name=$dml-doc/nydml:dml/nydml:enum/@name]">
        <foreign-key name="{concat($name, '_FK_', @name)}" foreignTable="{nydml:type/@name}" onDelete="cascade">
          <reference local="{@name}" foreign="Id" /> 
        </foreign-key>
      </xsl:for-each>
    </xsl:if>
  </xsl:template>
  
  <!-- Creates a foreign key reference description for the selected extended domain -->
  <xsl:template match="nydml:domain" mode="sql-foreign-extended-references">
    <xsl:variable name="extends" select="@extends" />
    <xsl:variable name="extended" select="$dml-doc/nydml:dml/nydml:domain[@name=$extends]" />
    <xsl:choose>
      <xsl:when test="$extended">
        <xsl:apply-templates select="$extended" mode="sql-foreign-extended-references" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:for-each select="nydml:attribute[../nydml:key/@attributes=@name]">
          <xsl:element name="reference">
            <xsl:call-template name="sql-name-attribute">
              <xsl:with-param name="element" select="." />
              <xsl:with-param name="name" select="'local'" />
            </xsl:call-template>
            <xsl:call-template name="sql-name-attribute">
              <xsl:with-param name="element" select="." />
              <xsl:with-param name="name" select="'foreign'" />
            </xsl:call-template>
          </xsl:element>
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <!-- Creates a column for a foreign key for the selected association end -->
  <xsl:template match="nydml:end" mode="sql-foreign-element">
    <xsl:param name="name" />
    <xsl:param name="mode" />
    <xsl:param name="foreignTable" select="false()" />
    <xsl:param name="required" select="false()" />
    <xsl:variable name="n" select="@name" />
    <xsl:variable name="targetName" select="../nydml:end[@name!=$n]/@target" />
    <xsl:variable name="pname">
      <xsl:choose>
        <xsl:when test="string-length($name) &gt; 0">
          <xsl:value-of select="$name" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$targetName" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="$mode='sql-foreign-pk-columns'">
        <xsl:apply-templates select="$dml-doc/nydml:dml/nydml:domain[@name=$targetName]" mode="sql-foreign-pk-columns">
          <xsl:with-param name="pname" select="$pname" />
          <xsl:with-param name="foreignTable" select="$foreignTable" />
          <xsl:with-param name="required" select="$required" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:when test="$mode='sql-foreign-pk-fields'">
        <xsl:apply-templates select="$dml-doc/nydml:dml/nydml:domain[@name=$targetName]" mode="sql-foreign-pk-fields">
          <xsl:with-param name="pname" select="$pname" />
          <xsl:with-param name="foreignTable" select="$foreignTable" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:when test="$mode='foreign-data-fields'">
        <xsl:apply-templates select="$dml-doc/nydml:dml/nydml:domain[@name=$targetName]" mode="foreign-data-fields">
          <xsl:with-param name="pname" select="$pname" />
          <xsl:with-param name="foreignTable" select="$foreignTable" />
          <xsl:with-param name="required" select="$required" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:when test="$mode='foreign-interface-properties'">
        <xsl:apply-templates select="$dml-doc/nydml:dml/nydml:domain[@name=$targetName]" mode="foreign-interface-properties">
          <xsl:with-param name="name" select="$name" />
          <xsl:with-param name="pname" select="$pname" />
          <xsl:with-param name="foreignTable" select="$foreignTable" />
          <xsl:with-param name="required" select="$required" />
        </xsl:apply-templates>
      </xsl:when>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="nydml:end" mode="sql-foreign-column">
    <xsl:param name="name" />
    <xsl:param name="required" select="false()" />
    <xsl:param name="foreignTable" select="false()" />
    <xsl:apply-templates select="." mode="sql-foreign-element">
      <xsl:with-param name="name" select="$name" />
      <xsl:with-param name="foreignTable" select="$foreignTable" />
      <xsl:with-param name="required" select="$required" />
      <xsl:with-param name="mode" select="'sql-foreign-pk-columns'" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="nydml:end" mode="foreign-data">
    <xsl:param name="name" />
    <xsl:param name="foreignTable" select="false()" />
    <xsl:param name="required" select="false()" />
    <xsl:apply-templates select="." mode="sql-foreign-element">
      <xsl:with-param name="name" select="$name" />
      <xsl:with-param name="foreignTable" select="$foreignTable" />
      <xsl:with-param name="required" select="$required" />
      <xsl:with-param name="mode" select="'foreign-data-fields'" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="nydml:end" mode="foreign-interface">
    <xsl:param name="name" />
    <xsl:param name="foreignTable" select="false()" />
    <xsl:param name="required" select="false()" />
    <xsl:apply-templates select="." mode="sql-foreign-element">
      <xsl:with-param name="name" select="$name" />
      <xsl:with-param name="foreignTable" select="$foreignTable" />
      <xsl:with-param name="required" select="$required" />
      <xsl:with-param name="mode" select="'foreign-interface-properties'" />
    </xsl:apply-templates>
  </xsl:template>
  
  <!-- Creates a primary key column for a foreign key for the selected association end -->
  <xsl:template match="nydml:domain" mode="sql-foreign-pk-columns">
    <xsl:param name="pname" />
    <xsl:param name="required" select="false()" />
    <xsl:param name="foreignTable" select="false()" />
    <xsl:variable name="extends" select="@extends" />
    <xsl:variable name="extended" select="$dml-doc/nydml:dml/nydml:domain[@name=$extends]" />
    <xsl:choose>
      <xsl:when test="$extended">
        <xsl:apply-templates select="$extended" mode="sql-foreign-pk-columns">
          <xsl:with-param name="pname" select="$pname" />
          <xsl:with-param name="foreignTable" select="$foreignTable" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
        <xsl:for-each select="nydml:attribute[../nydml:key/@attributes=@name]">
          <xsl:element name="column">
            <xsl:call-template name="sql-name-attribute">
              <xsl:with-param name="element" select="." />
              <xsl:with-param name="prefix" select="concat($pname, '_')" />
            </xsl:call-template>
            <xsl:call-template name="sql-type-attributes">
              <xsl:with-param name="type" select="nydml:type" />
              <xsl:with-param name="size" select="nydml:type/@size" />
            </xsl:call-template>
            <xsl:choose>
              <xsl:when test="$foreignTable">
                <xsl:attribute name="primaryKey">true</xsl:attribute>
                <xsl:attribute name="required">true</xsl:attribute>
              </xsl:when>
              <xsl:when test="$required">
                <xsl:attribute name="required">true</xsl:attribute>
              </xsl:when>
            </xsl:choose>
          </xsl:element>
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <!-- Creates a foreign key description for the selected association end -->
  <xsl:template match="nydml:end" mode="sql-foreign-key">
    <xsl:param name="name" />
    <xsl:param name="foreignTable" select="false()" />
    <xsl:variable name="ua" select="count(../nydml:end[@multiplicity='0..1' or @multiplicity='1'])" />
    <xsl:variable name="na" select="count(../nydml:attribute)" />
    <xsl:variable name="bf" select="$ua=2 or ($ua=1 and $na &gt; 0)" />
    <xsl:variable name="ft" select="$foreignTable or $bf" />
    <xsl:variable name="n" select="@name" />
    <xsl:variable name="target" select="../nydml:end[@name!=$n]/@target" />
    <xsl:variable name="targetName">
      <xsl:value-of select="$target" />
    </xsl:variable>
    <xsl:variable name="pname">
      <xsl:choose>
        <xsl:when test="string-length($name) &gt; 0">
          <xsl:value-of select="$name" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$targetName" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:element name="foreign-key">
      <xsl:choose>
        <xsl:when test="$foreignTable">
          <xsl:call-template name="sql-name-attribute">
            <xsl:with-param name="element" select="../nydml:end[@name!=$n]" />
            <xsl:with-param name="prefix" select="concat(../@name, '_FK_')" />
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:call-template name="sql-name-attribute">
            <xsl:with-param name="element" select="../nydml:end[@name!=$n]" />
            <xsl:with-param name="prefix" select="concat(@target, '_FK_')" />
          </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>
          <xsl:call-template name="sql-name-attribute">
            <xsl:with-param name="element" select="$dml-doc/nydml:dml/nydml:domain[@name=$targetName]" />
            <xsl:with-param name="name" select="'foreignTable'" />
          </xsl:call-template>
      <xsl:attribute name="onDelete">
        <xsl:choose>
          <xsl:when test="$ft or ../@association='composition'">
            <xsl:text>cascade</xsl:text>
          </xsl:when>
          <xsl:when test="../@association='aggregation'">
            <xsl:text>setnull</xsl:text>
          </xsl:when>
          <xsl:otherwise>
            <xsl:text>none</xsl:text>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <xsl:choose>
        <xsl:when test="$bf">
          <xsl:apply-templates select="$dml-doc/nydml:dml/nydml:domain[@name=$target]" mode="sql-foreign-pk-keys">
            <xsl:with-param name="pname" select="$pname" />
            <xsl:with-param name="foreignTable" select="$ft" />
          </xsl:apply-templates>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="$dml-doc/nydml:dml/nydml:domain[@name=$targetName]" mode="sql-foreign-pk-keys">
            <xsl:with-param name="pname" select="$pname" />
            <xsl:with-param name="foreignTable" select="$ft" />
          </xsl:apply-templates>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:element>
  </xsl:template>
  
  <!-- Creates a primary key column for a foreign key for the selected association end -->
  <xsl:template match="nydml:domain" mode="sql-foreign-pk-keys">
    <xsl:param name="pname" />
    <xsl:param name="foreignTable" select="false()" />
    <xsl:variable name="extends" select="@extends" />
    <xsl:variable name="extended" select="$dml-doc/nydml:dml/nydml:domain[@name=$extends]" />
    <xsl:choose>
      <xsl:when test="$extended">
        <xsl:apply-templates select="$extended" mode="sql-foreign-pk-keys">
          <xsl:with-param name="pname" select="$pname" />
          <xsl:with-param name="foreignTable" select="$foreignTable" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
        <xsl:for-each select="nydml:attribute[../nydml:key/@attributes=@name]">
          <xsl:element name="reference">
            <xsl:call-template name="sql-name-attribute">
              <xsl:with-param name="element" select="." />
              <xsl:with-param name="prefix" select="concat($pname, '_')" />
              <xsl:with-param name="name" select="'local'" />
            </xsl:call-template>
            <xsl:call-template name="sql-name-attribute">
              <xsl:with-param name="element" select="." />
              <xsl:with-param name="name" select="'foreign'" />
            </xsl:call-template>
          </xsl:element>
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <!-- Creates a primary key column for a foreign key for the selected association end -->
  <xsl:template match="nydml:domain" mode="sql-foreign-pk-fields">
    <xsl:param name="pname" />
    <xsl:param name="foreignTable" select="false()" />
    <xsl:variable name="extends" select="@extends" />
    <xsl:variable name="extended" select="$dml-doc/nydml:dml/nydml:domain[@name=$extends]" />
    <xsl:choose>
      <xsl:when test="$extended">
        <xsl:apply-templates select="$extended" mode="sql-foreign-pk-fields">
          <xsl:with-param name="pname" select="$pname" />
          <xsl:with-param name="foreignTable" select="$foreignTable" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
        <xsl:for-each select="nydml:attribute[../nydml:key/@attributes=@name]">
          <xsl:element name="field">
            <xsl:call-template name="sql-name-attribute">
              <xsl:with-param name="element" select="." />
              <xsl:with-param name="prefix" select="concat($pname, '_')" />
            </xsl:call-template>
          </xsl:element>
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <!-- Creates a primary key column for a foreign key for the selected association end -->
  <xsl:template match="nydml:domain" mode="foreign-data-fields">
    <xsl:param name="pname" />
    <xsl:param name="foreignTable" select="false()" />
    <xsl:param name="required" select="false()" />
    <xsl:variable name="extends" select="@extends" />
    <xsl:variable name="extended" select="$dml-doc/nydml:dml/nydml:domain[@name=$extends]" />
    <xsl:choose>
      <xsl:when test="$extended">
        <xsl:apply-templates select="$extended" mode="foreign-data-fields">
          <xsl:with-param name="pname" select="$pname" />
          <xsl:with-param name="foreignTable" select="$foreignTable" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
        <xsl:for-each select="nydml:attribute[../nydml:key/@attributes=@name]">
          <xsl:element name="field">
            <!-- Name of the field -->
            <xsl:call-template name="sql-name-attribute">
              <xsl:with-param name="element" select="." />
              <xsl:with-param name="prefix" select="concat($pname, '_')" />
            </xsl:call-template>
            <!-- Name of the column -->
            <xsl:call-template name="sql-name-attribute">
              <xsl:with-param name="element" select="." />
              <xsl:with-param name="prefix" select="concat($pname, '_')" />
              <xsl:with-param name="name">
                <xsl:text>column</xsl:text>
              </xsl:with-param>
            </xsl:call-template>
            <!-- Type of the field -->
            <xsl:call-template name="data-type-attributes">
              <xsl:with-param name="type" select="nydml:type" />
              <xsl:with-param name="required">
                <xsl:if test="not($required) or not(@required) or @required='false'">
                  <xsl:text>false</xsl:text>
                </xsl:if>
              </xsl:with-param>
            </xsl:call-template>
          </xsl:element>
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <!-- Creates a primary key column for a foreign key for the selected association end -->
  <xsl:template match="nydml:domain" mode="data-pk-fields">
    <xsl:variable name="extends" select="@extends" />
    <xsl:variable name="extended" select="$dml-doc/nydml:dml/nydml:domain[@name=$extends]" />
    <xsl:choose>
      <xsl:when test="$extended">
<!--        <xsl:apply-templates select="$extended" mode="data-pk-fields" /> -->
      </xsl:when>
      <xsl:otherwise>
        <xsl:for-each select="nydml:attribute[../nydml:key/@attributes=@name]">
          <xsl:apply-templates select="." mode="data-field" />
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <!-- Creates a primary key column for a foreign key for the selected association end -->
  <xsl:template match="nydml:domain" mode="foreign-interface-properties">
    <xsl:param name="name" />
    <xsl:param name="pname" />
    <xsl:param name="foreignTable" select="false()" />
    <xsl:param name="required" select="false()" />
    <xsl:element name="property">
      <xsl:attribute name="name">
        <xsl:value-of select="$name" />
      </xsl:attribute>
      <xsl:apply-templates select="." mode="foreign-interface-properties-fields">
        <xsl:with-param name="pname" select="$pname" />
        <xsl:with-param name="foreignTable" select="$foreignTable" />
        <xsl:with-param name="required" select="$required" />
      </xsl:apply-templates>
      <xsl:attribute name="type">
        <xsl:choose>
          <xsl:when test="$foreignTable">
            <xsl:value-of select="$name" />
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="@name" />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <xsl:if test="$required">
        <xsl:attribute name="required">
          <xsl:text>true</xsl:text>
        </xsl:attribute>
      </xsl:if>
      <accessor getter="public" setter="public" />
     </xsl:element>
  </xsl:template>
  
  <!-- Creates a primary key column for a foreign key for the selected association end -->
  <xsl:template match="nydml:domain" mode="foreign-interface-properties-fields">
    <xsl:param name="pname" />
    <xsl:param name="foreignTable" select="false()" />
    <xsl:param name="required" select="false()" />
    <xsl:variable name="extends" select="@extends" />
    <xsl:variable name="extended" select="$dml-doc/nydml:dml/nydml:domain[@name=$extends]" />
    <xsl:choose>
      <xsl:when test="$extended">
        <xsl:apply-templates select="$extended" mode="foreign-interface-properties-fields">
          <xsl:with-param name="pname" select="$pname" />
          <xsl:with-param name="foreignTable" select="$foreignTable" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
          <xsl:choose>
            <xsl:when test="count(nydml:attribute[../nydml:key/@attributes=@name])=1">
                  <xsl:call-template name="sql-name-attribute">
                    <xsl:with-param name="element" select="nydml:attribute[../nydml:key/@attributes=@name]" />
                    <xsl:with-param name="prefix" select="concat($pname, '_')" />
                    <xsl:with-param name="name">
                      <xsl:text>field</xsl:text>
                    </xsl:with-param>
                  </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
              <xsl:for-each select="nydml:attribute[../nydml:key/@attributes=@name]">
                  <xsl:call-template name="sql-name-attribute">
                    <xsl:with-param name="element" select="nydml:attribute[../nydml:key/@attributes=@name]" />
                    <xsl:with-param name="prefix" select="concat($pname, '_')" />
                    <xsl:with-param name="name">
                      <xsl:text>field</xsl:text>
                    </xsl:with-param>
                  </xsl:call-template>
                <xsl:text> </xsl:text>
              </xsl:for-each>
            </xsl:otherwise>
          </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template name="sql-foreign-extended">
    <xsl:param name="name" />
    <xsl:param name="extends" />
    <xsl:variable name="extended" select="$dml-doc/nydml:dml/nydml:domain[@name=$extends]" />
    <foreign-key name="{concat($name, '_FK_', $extends)}">
      <xsl:call-template name="sql-name-attribute">
        <xsl:with-param name="element" select="$extended" />
        <xsl:with-param name="name" select="'foreignTable'" />
      </xsl:call-template>
      <xsl:attribute name="onDelete">
        <xsl:text>cascade</xsl:text>
      </xsl:attribute>
      <xsl:apply-templates select="$extended" mode="sql-foreign-extended-references" />
    </foreign-key>
  </xsl:template>
  
  <!-- Creates a table for the selected association description -->
  <xsl:template match="nydml:assoc" mode="sql-foreign-table">
    <xsl:element name="table">
      <!-- Name of the table -->
      <xsl:call-template name="sql-name-attribute">
        <xsl:with-param name="element" select="." />
      </xsl:call-template>
      <!-- Columns -->
      <xsl:variable name="ua" select="count(nydml:end[@multiplicity!='0..1' and @multiplicity!='1'])" />
      <xsl:if test="$ua!=0">
        <!-- Columns -->
        <xsl:apply-templates select="nydml:end" mode="sql-foreign-element">
          <xsl:with-param name="foreignTable" select="true()" />
          <xsl:with-param name="mode" select="'sql-foreign-pk-columns'" />
          <xsl:with-param name="name" select="name" />
        </xsl:apply-templates>
        <!-- Foreign keys -->
        <xsl:apply-templates select="nydml:end" mode="sql-foreign-key">
          <xsl:with-param name="foreignTable" select="true()" />
        </xsl:apply-templates>
      </xsl:if>
      <xsl:apply-templates select="nydml:attribute" mode="sql-column" />
    </xsl:element>
  </xsl:template>
  
  <!-- Creates a table for the selected enumeration description -->
  <xsl:template match="nydml:enum" mode="sql-foreign-table">
    <xsl:element name="table">
      <!-- Name of the table -->
      <xsl:call-template name="sql-name-attribute">
        <xsl:with-param name="element" select="." />
      </xsl:call-template>
      <!-- Columns -->
      <xsl:element name="column">
        <xsl:attribute name="name">Id</xsl:attribute>
        <xsl:call-template name="sql-type-attributes">
          <xsl:with-param name="type" select="nydml:base" />
          <xsl:with-param name="size" select="nydml:base/@size" />
        </xsl:call-template>
        <xsl:attribute name="primaryKey">true</xsl:attribute>
        <xsl:attribute name="required">true</xsl:attribute>
      </xsl:element>
      <column name="Libelle" type="VARCHAR" size="127" />
    </xsl:element>
  </xsl:template>

  <!-- Creates a column description for the selected attribute description -->
  <xsl:template match="nydml:attribute" mode="sql-column">
    <column>
      <!-- Name of the column -->
      <xsl:call-template name="sql-name-attribute">
        <xsl:with-param name="element" select="." />
      </xsl:call-template>
      <!-- Type of the column -->
      <xsl:call-template name="sql-type-attributes">
        <xsl:with-param name="type" select="nydml:type" />
        <xsl:with-param name="size" select="nydml:type/@size" />
      </xsl:call-template>
      <!-- Other characteristics (primary key, required) -->
      <xsl:choose>
        <xsl:when test="../nydml:key/@attributes=@name">
          <xsl:attribute name="primaryKey">true</xsl:attribute>
          <xsl:attribute name="autoIncrement">true</xsl:attribute>
          <xsl:attribute name="required">true</xsl:attribute>
        </xsl:when>
        <xsl:otherwise>
          <xsl:if test="@required='true'">
            <xsl:attribute name="required">true</xsl:attribute>
          </xsl:if>
        </xsl:otherwise>
      </xsl:choose>
    </column>
  </xsl:template>

  <!-- Creates a column description for the selected attribute description -->
  <xsl:template match="nydml:end" mode="sql-column">
    <xsl:param name="name" />
    <xsl:variable name="ua" select="count(../nydml:end[@multiplicity='0..1' or @multiplicity='1'])" />
    <xsl:if test="($ua=2 and ../nydml:end[@target=$name and position()=1]) or ($ua=1 and @multiplicity!='1' and @multiplicity!='0..1')">
      <xsl:for-each select="../nydml:attribute">
        <xsl:sort select="not(boolean(nydml:type[@name=../../../nydml:enum/@name]))" />
        <column>
          <!-- Name of the column -->
          <xsl:call-template name="sql-name-attribute">
            <xsl:with-param name="element" select="." />
          </xsl:call-template>
          <!-- Type of the column -->
          <xsl:call-template name="sql-type-attributes">
            <xsl:with-param name="type" select="nydml:type" />
            <xsl:with-param name="size" select="nydml:type/@size" />
          </xsl:call-template>
          <!-- Other characteristics (primary key, required) -->
          <xsl:if test="@required='true'">
            <xsl:attribute name="required">true</xsl:attribute>
          </xsl:if>
        </column>
      </xsl:for-each>
    </xsl:if>
  </xsl:template>

  <!-- Creates a primary key column description for the selected attribute description -->
  <xsl:template match="nydml:domain" mode="sql-pk-columns">
    <xsl:variable name="extends" select="@extends" />
    <xsl:variable name="extended" select="$dml-doc/nydml:dml/nydml:domain[@name=$extends]" />
    <xsl:choose>
      <xsl:when test="$extended">
        <xsl:apply-templates select="$extended" mode="sql-pk-columns" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="nydml:attribute[../nydml:key/@attributes=@name]" mode="sql-column" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- Creates a column description for the selected attribute description -->
  <xsl:template match="nydml:attribute" mode="data-field">
    <field>
      <!-- Name of the field -->
      <xsl:call-template name="sql-name-attribute">
        <xsl:with-param name="element" select="." />
      </xsl:call-template>
      <!-- Name of the column -->
      <xsl:call-template name="sql-name-attribute">
        <xsl:with-param name="element" select="." />
        <xsl:with-param name="name">
          <xsl:text>column</xsl:text>
        </xsl:with-param>
      </xsl:call-template>
      <!-- Type of the field -->
      <xsl:call-template name="data-type-attributes">
        <xsl:with-param name="type" select="nydml:type" />
        <xsl:with-param name="required">
          <xsl:if test="not(@required) or @required='false'">
            <xsl:text>false</xsl:text>
          </xsl:if>
        </xsl:with-param>
      </xsl:call-template>
    </field>
  </xsl:template>

  <xsl:template match="nydml:end" mode="data-field-element">
    <xsl:apply-templates select="." mode="sql-foreign-element">
      <xsl:with-param name="foreignTable" select="true()" />
      <xsl:with-param name="required" select="true()" />
      <xsl:with-param name="mode" select="'foreign-data-fields'" />
    </xsl:apply-templates>
  </xsl:template>

  <!-- Creates a column description for the selected attribute description -->
  <xsl:template match="nydml:assoc" mode="data-field">
    <xsl:variable name="ua" select="count(nydml:end[@multiplicity='0..1' or @multiplicity='1'])" />
    <xsl:choose>
      <xsl:when test="$ua=2">
        <xsl:for-each select="nydml:end">
          <xsl:if test="position()=1">
            <xsl:variable name="t" select="@target" />
            <xsl:apply-templates select="$dml-doc/nydml:dml/nydml:domain[@name=$t]" mode="data-pk-fields" />
          </xsl:if>
        </xsl:for-each>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="." mode="data-field-element" />
      </xsl:otherwise>
    </xsl:choose>

    <!-- ...then other columns. -->
    <xsl:apply-templates select="nydml:attribute[not(@visibility) or @visibility!='none']" mode="data-field" />
  </xsl:template>

  <xsl:template match="nydml:end" mode="interface-property-element">
    <xsl:apply-templates select="." mode="sql-foreign-element">
      <xsl:with-param name="name" select="@target" />
      <xsl:with-param name="foreignTable" select="true()" />
      <xsl:with-param name="required" select="true()" />
      <xsl:with-param name="mode" select="'foreign-interface-properties'" />
    </xsl:apply-templates>
  </xsl:template>

  <!-- Creates a column description for the selected attribute description -->
  <xsl:template match="nydml:assoc" mode="interface-property">
    <xsl:variable name="ua" select="count(nydml:end[@multiplicity='0..1' or @multiplicity='1'])" />
    <xsl:choose>
      <xsl:when test="$ua=2">
        <xsl:for-each select="nydml:end">
          <xsl:if test="position()=1">
            <xsl:variable name="name" select="@name" />
            <xsl:variable name="oe" select="../nydml:end[@target!=$name]" />
            <xsl:apply-templates select="." mode="sql-foreign-element">
              <xsl:with-param name="name" select="$oe/@target" />
              <xsl:with-param name="required" select="true()" />
              <xsl:with-param name="mode" select="'foreign-interface-properties'" />
              <xsl:with-param name="foreignTable" select="false()" />
            </xsl:apply-templates>
          </xsl:if>
        </xsl:for-each>
      </xsl:when>
      <xsl:otherwise>
        <xsl:for-each select="nydml:end">
          <xsl:apply-templates select="." mode="interface-property-element" />
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>

    <!-- ...then other columns. -->
    <xsl:apply-templates select="nydml:attribute[not(@visibility) or @visibility!='none']" mode="interface-property" />
  </xsl:template>

  <!-- Creates a column description for the selected attribute description -->
  <xsl:template match="nydml:attribute" mode="pk-field">
    <xsl:variable name="n" select="@name" />
    <xsl:if test="../nydml:key[@attributes=$n]">
      <field>
        <!-- Name of the field -->
        <xsl:call-template name="sql-name-attribute">
          <xsl:with-param name="element" select="." />
        </xsl:call-template>
      </field>
    </xsl:if>
  </xsl:template>

  <xsl:template match="nydml:end" mode="pk-field-element">
    <xsl:apply-templates select="." mode="sql-foreign-element">
      <xsl:with-param name="foreignTable" select="true()" />
      <xsl:with-param name="mode" select="'sql-foreign-pk-fields'" />
    </xsl:apply-templates>
  </xsl:template>
  
  <xsl:template match="nydml:domain" mode="pk-field">
    <xsl:variable name="extends" select="@extends" />
    <xsl:variable name="extended" select="$dml-doc/nydml:dml/nydml:domain[@name=$extends]" />
    <xsl:choose>
      <xsl:when test="$extended">
        <xsl:apply-templates select="$extended" mode="pk-field" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:attribute name="ref">
          <xsl:value-of select="@name" />
        </xsl:attribute>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <!-- Creates a column description for the selected association description -->
  <xsl:template match="nydml:assoc" mode="pk-field">
    <xsl:variable name="ua" select="count(nydml:end[@multiplicity='0..1' or @multiplicity='1'])" />
<!--    <xsl:choose>
      <xsl:when test="$ua &gt; 0">
        <xsl:variable name="t" select="nydml:end[2]/@target" />
        <xsl:apply-templates select="$dml-doc/nydml:dml/nydml:domain[@name=$t]" mode="pk-field" />
      </xsl:when>
      <xsl:otherwise> -->
        <xsl:apply-templates select="nydml:end" mode="sql-foreign-element">
          <xsl:with-param name="foreignTable" select="true()" />
          <xsl:with-param name="mode" select="'sql-foreign-pk-fields'" />
        </xsl:apply-templates>
<!--      </xsl:otherwise>
    </xsl:choose> -->
  </xsl:template>

  <!-- Creates a column description for the selected attribute description -->
  <xsl:template match="nydml:attribute" mode="interface-property">
    <property>
      <!-- Name of the field -->
      <xsl:call-template name="sql-name-attribute">
        <xsl:with-param name="element" select="." />
      </xsl:call-template>
      <!-- Name of the field -->
      <xsl:call-template name="sql-name-attribute">
        <xsl:with-param name="element" select="." />
        <xsl:with-param name="name">
          <xsl:text>field</xsl:text>
        </xsl:with-param>
      </xsl:call-template>
      <!-- Type of the field -->
      <xsl:call-template name="interface-type-attributes">
        <xsl:with-param name="type" select="nydml:type" />
        <xsl:with-param name="required">
          <xsl:if test="not(@required) or @required='false'">
            <xsl:text>false</xsl:text>
          </xsl:if>
        </xsl:with-param>
      </xsl:call-template>
      <accessor>
        <xsl:attribute name="getter">
          <xsl:choose>
            <xsl:when test="@visibility='internal'">
              <xsl:text>internal</xsl:text>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>public</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
        <xsl:attribute name="setter">
          <xsl:choose>
            <xsl:when test="@visibility='internal' or @visibility='readonly'">
              <xsl:text>internal</xsl:text>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>public</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
      </accessor>
    </property>
  </xsl:template>

  <!-- Creates a table description for the selected domain model description -->
  <xsl:template match="nydml:domain">
    <domain name="{@name}">
      <xsl:variable name="name" select="@name" />
      <xsl:if test="@extends">
        <xsl:attribute name="extends">
          <xsl:value-of select="@extends" />
        </xsl:attribute>
      </xsl:if>
      <table>
        <!-- Name of the table -->
        <xsl:call-template name="sql-name-attribute">
          <xsl:with-param name="element" select="." />
        </xsl:call-template>
        <!-- Primary key columns first... -->
        <xsl:apply-templates select="." mode="sql-pk-columns" />
        <!-- ...then foreign key columns... -->
        <xsl:call-template name="sql-foreign-item">
          <xsl:with-param name="name" select="$name" />
          <xsl:with-param name="mode">foreign-column</xsl:with-param>
        </xsl:call-template>
        <!-- ...then other columns. -->
        <xsl:apply-templates select="nydml:attribute[../nydml:key/@attributes!=@name]" mode="sql-column">
          <xsl:sort select="not(boolean(nydml:type[@name=../../../nydml:enum/@name]))" />
        </xsl:apply-templates>
  
        <!-- Describes the foreign keys for the table -->
        <xsl:call-template name="sql-foreign-item">
          <xsl:with-param name="name" select="$name" />
          <xsl:with-param name="mode">foreign-key</xsl:with-param>
        </xsl:call-template>
      </table>
      <!-- Primary key columns... -->
      <pk>
        <xsl:choose>
          <xsl:when test="@extends">
            <xsl:apply-templates select="." mode="pk-field" />
          </xsl:when>
          <xsl:otherwise>
            <xsl:apply-templates select="nydml:attribute[../nydml:key/@attributes=@name]" mode="pk-field" />
          </xsl:otherwise>
        </xsl:choose>
      </pk>
      <data>
        <xsl:attribute name="namespace">
          <xsl:value-of select="$namespace-base-name" />
          <xsl:text>domainmodel/</xsl:text>
        </xsl:attribute>
        <!-- Primary key columns first... -->
        <xsl:apply-templates select="." mode="data-pk-fields" />
        <!-- ...then foreign key columns... -->
        <xsl:call-template name="sql-foreign-item">
          <xsl:with-param name="name" select="$name" />
          <xsl:with-param name="mode">foreign-data</xsl:with-param>
        </xsl:call-template>
        <!-- ...then other columns. -->
        <xsl:apply-templates select="nydml:attribute[../nydml:key/@attributes!=@name and (not(@visibility) or @visibility!='none')]" mode="data-field">
          <xsl:sort select="not(boolean(nydml:type[@name=../../../nydml:enum/@name]))" />
        </xsl:apply-templates>
      </data>
      <interface>
        <!-- ...then foreign key columns... -->
        <xsl:call-template name="sql-foreign-item">
          <xsl:with-param name="name" select="$name" />
          <xsl:with-param name="mode">foreign-interface</xsl:with-param>
        </xsl:call-template>
        <!-- ...then other columns. -->
        <xsl:apply-templates select="nydml:attribute[../nydml:key/@attributes!=@name and (not(@visibility) or @visibility!='none')]" mode="interface-property" />
      </interface>
    </domain>
  </xsl:template>
  
  <!-- Creates a table for the selected association description -->
  <xsl:template match="nydml:assoc" mode="foreign-domain">
    <xsl:variable name="ua" select="count(nydml:end[@multiplicity='0..1' or @multiplicity='1'])" />
    <xsl:variable name="na" select="count(nydml:attribute)" />
    <xsl:if test="$ua=0 or ($ua=1 and $na &gt;0)">
      <domain name="{@name}">
        <xsl:if test="$na=0">
          <xsl:attribute name="visibility">
            <xsl:text>internal</xsl:text>
          </xsl:attribute>
        </xsl:if>
        <xsl:apply-templates select="." mode="sql-foreign-table" />
        <pk>
          <xsl:apply-templates select="." mode="pk-field" />
        </pk>
        <data>
          <xsl:attribute name="namespace">
            <xsl:value-of select="$namespace-base-name" />
            <xsl:text>domainmodel/</xsl:text>
          </xsl:attribute>
          <xsl:apply-templates select="." mode="data-field" />
        </data>
        <interface>
          <xsl:apply-templates select="." mode="interface-property" />
        </interface>
      </domain>
    </xsl:if>
  </xsl:template>

  <xsl:template match="nydml:enum">
    <enum name="{@name}">
      <xsl:apply-templates select="." mode="sql-foreign-table" />
      <xsl:apply-templates select="nydml:value" />
    </enum>
  </xsl:template>
  
  <xsl:template match="nydml:value">
    <value name="{@name}" code="{@code}">
      <xsl:value-of select="." />
    </value>
  </xsl:template>

  <xsl:template name="types-definition">
    <types>
      <xsl:apply-templates select="$dml-doc/nydml:dml/nydml:enum">
        <xsl:sort select="@name" />
      </xsl:apply-templates>

      <!-- Domain model types description generation -->
      <xsl:apply-templates select="$dml-doc/nydml:dml/nydml:domain">
        <xsl:sort select="@name" />
      </xsl:apply-templates>

      <!-- Association domain model types description generation -->
      <xsl:apply-templates select="$dml-doc/nydml:dml/nydml:assoc" mode="foreign-domain">
        <xsl:sort select="@name" />
      </xsl:apply-templates>
    </types>
  </xsl:template>

  <xsl:template name="project">
    <xsl:param name="name" />
    <xsl:param name="mode" />
    <xsl:param name="references" />
    <xsl:param name="files" />
    <xsl:param name="internals" />
    <xsl:variable name="id" select="nyext:getNewGuid()" />
    <directory name="{$name}">
      <project id="{concat('{', $id, '}')}" name="{$name}" assembly="{concat($project-base-name, '.', $name)}">
        <xsl:if test="$mode">
          <xsl:attribute name="mode">
            <xsl:value-of select="$mode" />
          </xsl:attribute>
        </xsl:if>
        <xsl:call-template name="generation">
          <xsl:with-param name="transform" select="'project.xslt'" />
          <xsl:with-param name="conflict" select="'merge'" />
        </xsl:call-template>
        <xsl:copy-of select="$references" />
        <xsl:copy-of select="$files" />
        <xsl:copy-of select="$internals" />
        <directory name="Properties">
          <file name="AssemblyInfo">
            <xsl:call-template name="generation">
              <xsl:with-param name="transform" select="'assemblyinfo.xslt'" />
              <xsl:with-param name="conflict" select="'merge'" />
              <xsl:with-param name="params">
                <param name="id" value="{$id}" />
                <param name="assembly" value="{concat($project-base-name, '.', $name)}" />
              </xsl:with-param>
            </xsl:call-template>
          </file>
        </directory>
      </project>
    </directory>
  </xsl:template>

  <xsl:template name="project-domainmodel"> 
    <xsl:variable name="package-name" select="concat($package-base-name, '.DomainModel')" />
    <xsl:variable name="project-name" select="'DomainModel'" />
    <xsl:call-template name="project">
      <xsl:with-param name="name" select="$project-name" />
      <xsl:with-param name="references">
        <reference name="Salamanca.Common" />
        <reference name="Salamanca.DataAccess" />
        <reference name="Salamanca.DataRules" />
        <reference name="System" />
        <reference name="System.Xml" />
      </xsl:with-param>
      <xsl:with-param name="files">
        <directory name="{$package-name}">
          <file name="Enums">
            <xsl:call-template name="generation">
              <xsl:with-param name="transform" select="'domainmodel-enums.xslt'" />
              <xsl:with-param name="conflict" select="'merge'" />
              <xsl:with-param name="params">
                <param name="package" value="{$package-name}" />
              </xsl:with-param>
            </xsl:call-template>
            <dependency name="{nyext:getModelFileName('Enums')}" generated="true" />
          </file>
          <xsl:for-each select="msxsl:node-set($types)/types/domain">
            <file name="{@name}">
              <xsl:call-template name="generation">
                <xsl:with-param name="transform" select="'domainmodel.xslt'" />
                <xsl:with-param name="conflict" select="'merge'" />
                <xsl:with-param name="params">
                  <param name="domainName" value="{@name}" />
                  <param name="package" value="{$package-name}" />
                </xsl:with-param>
              </xsl:call-template>
              <dependency name="{nyext:getModelFileName(@name)}" generated="true" />
            </file>
          </xsl:for-each>
          <directory name="Resources">
            <file name="SR" type="res">
              <xsl:call-template name="generation">
                <xsl:with-param name="transform" select="'domainmodel-res.xslt'" />
                <xsl:with-param name="conflict" select="'merge'" />
                <xsl:with-param name="params">
                  <param name="package" value="{concat($package-name, '.Resources')}" />
                </xsl:with-param>
              </xsl:call-template>
              <dependency name="{nyext:getDesignerFileName('SR')}" generated="true" design="true" />
            </file>
          </directory>
        </directory>
      </xsl:with-param>
      <xsl:with-param name="internals">
        <internal name="DomainModel.Data" />
        <internal name="DomainModel.EnterpriseLibrary" />
        <internal name="DomainModel.Web" />
      </xsl:with-param> 
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template name="project-datamapper-ado">
    <xsl:variable name="package-name" select="concat($package-base-name, '.DomainModel.Data')" />
    <xsl:variable name="project-name" select="'DomainModel.Data'" />
    <xsl:call-template name="project">
      <xsl:with-param name="name" select="$project-name" />
      <xsl:with-param name="references">
        <reference name="Salamanca.Common" />
        <reference name="Salamanca.DataAccess" />
        <reference name="Salamanca.DataAccess.Data" />
        <reference name="Salamanca.DataRules" />
        <reference name="System" />
        <reference name="System.Data" />
        <reference project="DomainModel" />
      </xsl:with-param>
      <xsl:with-param name="files">
        <directory name="{$package-name}">
          <xsl:for-each select="msxsl:node-set($types)/types/domain">
            <file name="{concat(@name, 'Mapper')}">
              <xsl:call-template name="generation">
                <xsl:with-param name="transform" select="'datamapper-data.xslt'" />
                <xsl:with-param name="conflict" select="'merge'" />
                <xsl:with-param name="params">
                  <param name="domainName" value="{@name}" />
                  <param name="package" value="{$package-name}" />
                </xsl:with-param>
              </xsl:call-template>
              <dependency name="{nyext:getModelFileName(concat(@name, 'Mapper'))}" generated="true" />
            </file>
          </xsl:for-each>
          <file name="Mappers">
            <xsl:call-template name="generation">
              <xsl:with-param name="transform" select="'datamapper-data-mappers.xslt'" />
              <xsl:with-param name="conflict" select="'merge'" />
              <xsl:with-param name="params">
                <param name="package" value="{$package-name}" />
              </xsl:with-param>
            </xsl:call-template>
            <dependency name="{nyext:getModelFileName('Mappers')}" generated="true" />
          </file>
          <directory name="Resources">
            <file name="Sql" type="res">
              <xsl:call-template name="generation">
                <xsl:with-param name="transform" select="'datamapper-data-res.xslt'" />
                <xsl:with-param name="conflict" select="'merge'" />
                <xsl:with-param name="params">
                  <param name="package" value="{concat($package-name, '.Resources')}" />
                </xsl:with-param>
              </xsl:call-template>
              <dependency name="{nyext:getDesignerFileName('Sql')}" generated="true" design="true" />
            </file>
          </directory>
        </directory>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template name="project-datamapper-daab">
    <xsl:variable name="package-name" select="concat($package-base-name, '.DomainModel.EnterpriseLibrary')" />
    <xsl:variable name="project-name" select="'DomainModel.EnterpriseLibrary'" />
    <xsl:call-template name="project">
      <xsl:with-param name="name" select="$project-name" />
      <xsl:with-param name="mode" select="'.NET'" />
      <xsl:with-param name="references">
        <reference name="Microsoft.Practices.EnterpriseLibrary.Common" />
        <reference name="Microsoft.Practices.EnterpriseLibrary.Data" />
        <reference name="Microsoft.Practices.ObjectBuilder" />
        <reference name="Salamanca.Common" />
        <reference name="Salamanca.DataAccess" />
        <reference name="Salamanca.DataAccess.EnterpriseLibrary" />
        <reference name="Salamanca.DataRules" />
        <reference name="System" />
        <reference name="System.Data" />
        <reference project="DomainModel" />
      </xsl:with-param>
      <xsl:with-param name="files">
        <directory name="{$package-name}">
          <xsl:for-each select="msxsl:node-set($types)/types/domain">
            <file name="{concat(@name, 'Mapper')}">
              <xsl:call-template name="generation">
                <xsl:with-param name="transform" select="'datamapper-daab.xslt'" />
                <xsl:with-param name="conflict" select="'merge'" />
                <xsl:with-param name="params">
                  <param name="domainName" value="{@name}" />
                  <param name="package" value="{$package-name}" />
                </xsl:with-param>
              </xsl:call-template>
              <dependency name="{nyext:getModelFileName(concat(@name, 'Mapper'))}" generated="true" />
            </file>
          </xsl:for-each>
          <file name="Mappers">
            <xsl:call-template name="generation">
              <xsl:with-param name="transform" select="'datamapper-daab-mappers.xslt'" />
              <xsl:with-param name="conflict" select="'merge'" />
              <xsl:with-param name="params">
                <param name="package" value="{$package-name}" />
              </xsl:with-param>
            </xsl:call-template>
            <dependency name="{nyext:getModelFileName('Mappers')}" generated="true" />
          </file>
          <directory name="Resources">
            <file name="Sql" type="res">
              <xsl:call-template name="generation">
                <xsl:with-param name="transform" select="'datamapper-data-res.xslt'" />
                <xsl:with-param name="conflict" select="'merge'" />
                <xsl:with-param name="params">
                  <param name="package" value="{concat($package-name, '.Resources')}" />
                </xsl:with-param>
              </xsl:call-template>
              <dependency name="{nyext:getDesignerFileName('Sql')}" generated="true" design="true" />
            </file>
          </directory>
        </directory>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template name="project-datamapper-web">
    <xsl:variable name="package-name" select="concat($package-base-name, '.DomainModel.Web')" />
    <xsl:variable name="project-name" select="'DomainModel.Web'" />
    <xsl:call-template name="project">
      <xsl:with-param name="name" select="$project-name" />
      <xsl:with-param name="references">
        <reference name="Salamanca.Common" />
        <reference name="Salamanca.DataAccess" />
        <reference name="System" />
        <reference name="System.Data" />
        <reference project="DomainModel" />
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template name="project-activities-crud">
    <xsl:variable name="package-name" select="concat($package-base-name, '.DomainModel.Activities')" />
    <xsl:variable name="project-name" select="'DomainModel.Activities'" />
    <xsl:call-template name="project">
      <xsl:with-param name="name" select="$project-name" />
      <xsl:with-param name="references">
        <reference name="Salamanca.Common" />
        <reference name="Salamanca.DataAccess" />
        <reference name="Salamanca.DataActivities" />
        <reference name="Salamanca.DataRules" />
        <reference name="System" />
        <reference name="System.Data" />
        <reference project="DomainModel" />
      </xsl:with-param>
      <xsl:with-param name="files">
        <directory name="{$package-name}">
          <xsl:for-each select="msxsl:node-set($types)/types/domain[not(@visibility) or @visibility='public']">
            <file name="{concat(@name, 'Crud')}">
              <xsl:call-template name="generation">
                <xsl:with-param name="transform" select="'domainmodel-activities.xslt'" />
                <xsl:with-param name="conflict" select="'overwrite'" />
                <xsl:with-param name="params">
                  <param name="domainName" value="{@name}" />
                  <param name="package" value="{$package-name}" />
                </xsl:with-param>
              </xsl:call-template>
              <dependency name="{nyext:getModelFileName(concat(@name, 'Crud'))}" generated="true" />
            </file>
          </xsl:for-each>
          <file name="Parameters">
            <xsl:call-template name="generation">
              <xsl:with-param name="transform" select="'domainmodel-activities-parameters.xslt'" />
              <xsl:with-param name="conflict" select="'merge'" />
              <xsl:with-param name="params">
                <param name="package" value="{$package-name}" />
              </xsl:with-param>
            </xsl:call-template>
            <dependency name="{nyext:getModelFileName('Parameters')}" generated="true" />
          </file>
<!--          <directory name="Data">
            <xsl:for-each select="msxsl:node-set($types)/types/domain[not(@visibility) or @visibility='public']">
            <file name="{concat(@name, 'CrudData')}">
              <xsl:call-template name="generation">
                <xsl:with-param name="transform" select="'domainmodel-activities-data.xslt'" />
                <xsl:with-param name="conflict" select="'overwrite'" />
                <xsl:with-param name="params">
                  <param name="domainName" value="{@name}" />
                  <param name="package" value="{concat($package-name, '.Data')}" />
                </xsl:with-param>
              </xsl:call-template>
              <dependency name="{nyext:getModelFileName(concat(@name, 'CrudData'))}" generated="true" />
            </file>
            </xsl:for-each>
          </directory>
          <directory name="Factories">
            <xsl:for-each select="msxsl:node-set($types)/types/domain[not(@visibility) or @visibility='public']">
            <file name="{concat(@name, 'CrudQuestionFactory')}">
              <xsl:call-template name="generation">
                <xsl:with-param name="transform" select="'domainmodel-activities-factory.xslt'" />
                <xsl:with-param name="conflict" select="'overwrite'" />
                <xsl:with-param name="params">
                  <param name="domainName" value="{@name}" />
                  <param name="package" value="{concat($package-name, '.Factory')}" />
                </xsl:with-param>
              </xsl:call-template>
              <dependency name="{nyext:getModelFileName(concat(@name, 'CrudQuestionFactory'))}" generated="true" />
            </file>
            </xsl:for-each>
          </directory>-->
        </directory>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template name="project-controls-web">
    <xsl:variable name="package-name" select="concat($package-base-name, '.Web.UI.Controls')" />
    <xsl:variable name="project-name" select="'Web.UI.WebControls'" />
    <xsl:call-template name="project">
      <xsl:with-param name="name" select="$project-name" />
      <xsl:with-param name="mode" select="'.NET'" />
      <xsl:with-param name="references">
        <reference name="Salamanca.Common" />
        <reference name="Salamanca.DataAccess" />
        <reference name="Salamanca.DataRules" />
        <reference name="System" />
        <reference name="System.Data" />
        <reference name="System.Drawing" />
        <reference name="System.Web" />
        <reference project="DomainModel" />
      </xsl:with-param>
      <xsl:with-param name="files">
        <directory name="{$package-name}">
          <file name="Enums">
            <xsl:call-template name="generation">
              <xsl:with-param name="transform" select="'domainmodel-ui-webcontrol-enums.xslt'" />
              <xsl:with-param name="conflict" select="'merge'" />
              <xsl:with-param name="params">
                <param name="package" value="{$package-name}" />
              </xsl:with-param>
            </xsl:call-template>
            <dependency name="{nyext:getModelFileName('Enums')}" generated="true" />
          </file>
          <xsl:for-each select="msxsl:node-set($types)/types/domain[not(@visibility) or @visibility='public']">
            <file name="{concat(@name, 'Control')}">
              <xsl:call-template name="generation">
                <xsl:with-param name="transform" select="'domainmodel-ui-webcontrol.xslt'" />
                <xsl:with-param name="conflict" select="'overwrite'" />
                <xsl:with-param name="params">
                  <param name="domainName" value="{@name}" />
                  <param name="package" value="{$package-name}" />
                </xsl:with-param>
              </xsl:call-template>
              <dependency name="{nyext:getModelFileName(concat(@name, 'Control'))}" generated="true" />
            </file>
            <file name="{concat(@name, 'Control')}" type="bmp">
              <xsl:call-template name="execution">
                <xsl:with-param name="command" select="'xcopy.exe'" />
                <xsl:with-param name="input" select="'res\Control.bmp'" />
                <xsl:with-param name="args" select="'{0} {1} /C /I /Q /R /Y'" />
              </xsl:call-template>
            </file>
          </xsl:for-each>
          <directory name="Resources">
            <file name="SR" type="res">
              <xsl:call-template name="generation">
                <xsl:with-param name="transform" select="'domainmodel-ui-control-res.xslt'" />
                <xsl:with-param name="conflict" select="'merge'" />
                <xsl:with-param name="params">
                  <param name="package" value="{concat($package-name, '.Resources')}" />
                </xsl:with-param>
              </xsl:call-template>
              <dependency name="{nyext:getDesignerFileName('SR')}" generated="true" design="true" />
            </file>
          </directory>
        </directory>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>
    
  <xsl:template name="project-controls-forms">
    <xsl:variable name="package-name" select="concat($package-base-name, '.UI.Forms.Controls')" />
    <xsl:variable name="project-name" select="'UI.Forms.Controls'" />
    <xsl:call-template name="project">
      <xsl:with-param name="name" select="$project-name" />
      <xsl:with-param name="mode" select="'.NET'" />
      <xsl:with-param name="references">
        <reference name="Salamanca.Common" />
        <reference name="Salamanca.DataAccess" />
        <reference name="Salamanca.DataRules" />
        <reference name="System" />
        <reference name="System.Data" />
        <reference name="System.Drawing" />
        <reference name="System.Windows.Forms" />
        <reference name="System.Xml" />
        <reference project="DomainModel" />
      </xsl:with-param>
      <xsl:with-param name="files">
        <directory name="{$package-name}">
          <xsl:for-each select="msxsl:node-set($types)/types/domain[not(@visibility) or @visibility='public']">
            <file name="{concat(@name, 'Control')}">
              <xsl:call-template name="generation">
                <xsl:with-param name="transform" select="'domainmodel-ui-formscontrol.xslt'" />
                <xsl:with-param name="conflict" select="'overwrite'" />
                <xsl:with-param name="params">
                  <param name="domainName" value="{@name}" />
                  <param name="package" value="{$package-name}" />
                </xsl:with-param>
              </xsl:call-template>
              <dependency name="{nyext:getDesignerFileName(concat(@name, 'Control'))}" generated="true" />
              <dependency name="{concat(@name, 'Control')}" generated="true" type="res"/>
            </file>
          </xsl:for-each>
          <!--<directory name="Resources">
            <file name="SR" type="res">
              <xsl:call-template name="generation">
                <xsl:with-param name="transform" select="'domainmodel-ui-control-res.xslt'" />
                <xsl:with-param name="conflict" select="'merge'" />
                <xsl:with-param name="params">
                  <param name="package" value="{concat($package-name, '.Resources')}" />
                </xsl:with-param>
              </xsl:call-template>
              <dependency name="{nyext:getDesignerFileName('SR')}" generated="true" design="true" />
            </file>
          </directory>-->
        </directory>
        <directory name="Properties">
<!--
          <directory name="DataSources">
            <xsl:for-each select="msxsl:node-set($types)/types/domain[not(@visibility) or @visibility='public']">
              <file name="{concat($package-base-name, '.DomainModel.', @name)}" type="datasource">
                <xsl:call-template name="generation">
                  <xsl:with-param name="transform" select="'domainmodel-ui-formscontrol-datasource.xslt'" />
                  <xsl:with-param name="conflict" select="'overwrite'" />
                  <xsl:with-param name="params">
                    <param name="package" value="{concat($package-base-name, '.DomainModel')}" />
                    <param name="assembly" value="{concat($project-base-name, '.DomainModel')}" />
                    <param name="domainName" value="{@name}" />
                  </xsl:with-param>
                </xsl:call-template>
              </file>
            </xsl:for-each>
          </directory>
-->
        </directory>
      </xsl:with-param>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="project-sql">
    <directory name="Sql">
      <project id="{nyext:getNewGuid()}" name="Sql" type="sql">
        <directory name="Change Scripts" />
        <directory name="Create Scripts">
          <file name="Create" type="sql">
            <xsl:call-template name="generation">
              <xsl:with-param name="transform" select="'sql.xslt'" />
              <xsl:with-param name="conflict" select="'overwrite'" />
            </xsl:call-template>
            <dependency name="{nyext:getModelFileName('Create')}" generated="true" />
            <dependency name="'Create'" generated="true" />
          </file>
        </directory>
        <directory name="Queries" />
      </project>
    </directory>
  </xsl:template>
  
  <xsl:template name="solution">
    <solution>
      <xsl:attribute name="name">
        <xsl:value-of select="concat(nyext:getFileName(nyp:project/@name), '.Model')" />
      </xsl:attribute>
      <xsl:call-template name="generation">
        <xsl:with-param name="transform" select="'solution.xslt'" />
        <xsl:with-param name="conflict" select="'merge'" />
      </xsl:call-template>
      <directory name="misc">
        <file name="Project" type="snk">
          <xsl:call-template name="execution">
            <xsl:with-param name="command" select="'sn.exe'" />
            <xsl:with-param name="args" select="'-q -k {1}'" />
          </xsl:call-template>
        </file>
      </directory>
      <directory name="Model">
        <xsl:call-template name="project-domainmodel" />
        <xsl:if test="nyp:project/nyp:dml/nyp:data[@mode='ADO .NET']">
          <xsl:call-template name="project-datamapper-ado" />
        </xsl:if>
        <xsl:if test="nyp:project/nyp:dml/nyp:data[@mode='Enterprise Library DAAB']">
          <xsl:call-template name="project-datamapper-daab" />
        </xsl:if>
        <xsl:if test="nyp:project/nyp:dml/nyp:data[@mode='Web Services']">
          <xsl:call-template name="project-datamapper-web" />
        </xsl:if>
        <xsl:call-template name="project-activities-crud" />
        <xsl:if test="nyp:project/nyp:dml/nyp:ui[@mode='Forms']">
          <xsl:call-template name="project-controls-forms" />
        </xsl:if>
        <xsl:if test="nyp:project/nyp:dml/nyp:ui[@mode='Web']">
          <xsl:call-template name="project-controls-web" />
        </xsl:if>
      </directory>
      <xsl:call-template name="project-sql" />
      <file name="build" type="bat">
        <xsl:call-template name="generation">
          <xsl:with-param name="transform" select="'build.xslt'" />
          <xsl:with-param name="conflict" select="'overwrite'" />
          <xsl:with-param name="params">
            <param name="solution" value="{nyext:getFileName(nyp:project/@name)}" />
          </xsl:with-param>
        </xsl:call-template>
      </file>
      <file name="{nyext:getFileName(nyp:project/@name)}" type="msbuild">
        <xsl:call-template name="generation">
          <xsl:with-param name="transform" select="'msbuild.xslt'" />
          <xsl:with-param name="conflict" select="'overwrite'" />
          <xsl:with-param name="params">
            <param name="solution" value="{nyext:getFileName(nyp:project/@name)}" />
          </xsl:with-param>
        </xsl:call-template>
      </file>
    </solution>
  </xsl:template>

  <xsl:template name="generation">
    <xsl:param name="input" />
    <xsl:param name="transform" />
    <xsl:param name="conflict" select="'overwrite'" />
    <xsl:param name="params" />
    <transformation>
      <xsl:if test="$input">
        <xsl:attribute name="input">
          <xsl:value-of select="$input" />
        </xsl:attribute>
      </xsl:if>
      <xsl:attribute name="transform">
        <xsl:value-of select="$transform" />
      </xsl:attribute>
      <xsl:attribute name="conflict">
        <xsl:value-of select="$conflict" />
      </xsl:attribute>
      <xsl:copy-of select="$params" />
    </transformation>
  </xsl:template>
  
  <xsl:template name="execution">
    <xsl:param name="input" />
    <xsl:param name="command" />
    <xsl:param name="args" />
    <execution>
      <xsl:if test="$input">
        <xsl:attribute name="input">
          <xsl:value-of select="$input" />
        </xsl:attribute>
      </xsl:if>
      <xsl:attribute name="command">
        <xsl:value-of select="$command" />
      </xsl:attribute>
      <xsl:attribute name="args">
        <xsl:value-of select="$args" />
      </xsl:attribute>
    </execution>
  </xsl:template>

  <xsl:template match="nyp:platform">
    <platform name="{@name}" mode="{@mode}" />
  </xsl:template>

  <!-- Entry point for the transformation -->
  <xsl:template match="/">
    <manifest>
      <configuration>
        <xsl:apply-templates select="nyp:project/nyp:platform" />
        <sql provider="{/nyp:project/nyp:dml/nyp:sql/@provider}" />
      </configuration>
      <xsl:copy-of select="$types" />
      <xsl:call-template name="solution" />
    </manifest>
  </xsl:template>
</xsl:stylesheet>
